﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ALDIOrganizer.Properties;
using Generator;

namespace ALDIOrganizer
{
    public partial class SetGeneratorParameters : Form
    {
        private const int HeightCollapsed = 232;
        private const int HeightExpanded = 660;
        private bool _isCollapsed;

        internal bool ShowReport
        {
            get
            {
                return cbShowReport.Checked;
            }
        }

        internal Parameters GetResulting
        {
            get
            {
                return parametersBindingSource.DataSource as Parameters;
            }
            set
            {
                parametersBindingSource.DataSource = value;
            }
        }

        static KeyValuePair<string, SpeedMode>[] GetSpeedModesDataSource
        {
            get
            {
                var express = new KeyValuePair<string, SpeedMode>
                    (Resources.SPEEDMODE_Express,
                    SpeedMode.Express);
                var fast = new KeyValuePair<string, SpeedMode>
                    (Resources.SPEEDMODE_Fast,
                    SpeedMode.Fast);
                var slow = new KeyValuePair<string, SpeedMode>
                    (Resources.SPEEDMODE_Slow,
                    SpeedMode.Slow);
                return new[] {express, fast, slow};
            }
        }
        /// <summary>
        /// adjusts the form size according to the Value of isCollapsed property.
        /// </summary>
        /// <remarks>
        /// When inCollapsed is false, more options is visible.
        /// btnMoreLessOptions is the button which toggles it.
        /// I achieve this by simply rescaling the form so that the extra controls
        /// are hidden from the user.
        /// NOTE: in theory user might still access them via keyboard (by pressing Tab)
        /// TODO: disable/re-enable those controls
        /// </remarks>
        private void collapseOrExtend()
        {
            Sounds.Play(Sounds.Validated);
            if (_isCollapsed)
            {
                this.Height = HeightCollapsed;
                btnMoreLessOptions.Text = Resources.FORM_SETGENERATORPAREMETERS_MoreSettings;
                btnMoreLessOptions.Image = Resources.down_arrow;
            }
            else
            {
                this.Height = HeightExpanded;
                btnMoreLessOptions.Text = Resources.FORM_SETGENERATORPAREMETERS_LessSettings;
                btnMoreLessOptions.Image = Resources.up_arrow;
            }            
            CenterToScreen();            
        }

        public Parameters BoundParameters;
        
        /* I need a class for databinding, because you can't bind to a struct.
         * (That is - technically, you can, but it will be read-only binding,
         * which isn't what I need) */
        
        
        public SetGeneratorParameters()
        {
            InitializeComponent();

            BoundParameters = new Parameters();
            parametersBindingSource.DataSource = BoundParameters;
            lbSpeedModes.DataSource = GetSpeedModesDataSource;
            lbSpeedModes.DisplayMember = "Key";
            lbSpeedModes.ValueMember = "Value";
            var index = -1;
            foreach (var foo in lbSpeedModes.Items)
            {
                try
                {
                    if (((KeyValuePair<string, SpeedMode>) lbSpeedModes.Items[++index]).Value ==
                        BoundParameters.Speed)
                    {
                        lbSpeedModes.SelectedIndex = index;
                        return;
                    }
                }
                catch (NullReferenceException) { }
            }
        }

        public SetGeneratorParameters(bool collapsed)
            : this()
        {
            _isCollapsed = collapsed;
            collapseOrExtend();
        }

        public SetGeneratorParameters(
            int pWeekNumber,
            string pTemplateName,
            bool collapsed,
            Parameters ep,
            Int64[] pLastWeekClosers)
            : this(collapsed)
        {   
            SetParameters(ep);
            GetLastWeekClosers = pLastWeekClosers;
            lbWhatItDoes.Text = lbWhatItDoes.Text.Replace(
                "#",
                pWeekNumber.ToString()).Replace(
                "$",
                pTemplateName);            
        }

        private void formGenerateRota_Load(object sender, EventArgs e)
        {
            ResetControls();
        }

        private void SetParameters(Parameters ep)
        {
            BoundParameters = ep;
            parametersBindingSource.DataSource = BoundParameters;
            parametersBindingSource.ResetBindings(false);
            
            
            ResetControls();
        }

        private void SetDefaultValues()
        {
            SetParameters(Parameters.GetDefaultParameters());            
            
        }

        private void ResetControls()
        {
            mbFullShifts.Enabled = cbAvoidInArow.Checked;
            mbFullShifts.ForeColor = cbAvoidInArow.Checked ? SystemColors.ControlText : Color.Transparent;

            var invalid = false;
            if (cbAvoidInArow.Checked)
            {
                byte b = 0;
                try
                {
                    b = Convert.ToByte(mbFullShifts.Text);
                }
                catch
                {
                    invalid = true;
                }
                if (b < 1 | b > 7)
                {
                    invalid = true;
                }
            }
            // validity
            {
                btnGo.Enabled = !invalid;
                mbFullShifts.ForeColor = invalid
                                             ? Color.Red
                                             : SystemColors.ControlText;
            }
            // max hours
            {
                tbMaxHoursSA.Enabled = cbMaximumHoursSA.Checked;
                tbMaxHoursSA.ForeColor = cbMaximumHoursSA.Checked ? SystemColors.ControlText : Color.Transparent;
                tbMaxHoursSR.Enabled = cbMaximumHoursSR.Checked;
                tbMaxHoursSR.ForeColor = cbMaximumHoursSR.Checked ? SystemColors.ControlText : Color.Transparent;
            }
            // keyflow
            {
                cbKeyFlowEveryone.Enabled = cbKeyflow.Checked;
                cbKeyFlowEveryone.Enabled = cbKeyflow.Checked;
                cbPreviousWeek.Enabled = cbKeyflow.Checked &&
                    GetLastWeekClosers.Length > 0;
            }
        }

        

        private void btnMoreLessOptions_Click(object sender, EventArgs e)
        {
            _isCollapsed = !_isCollapsed;
            collapseOrExtend();
        }

        private void cbKeyflow_CheckedChanged(object sender, EventArgs e)
        {
            ResetControls();            
        }

        private void cbMaximumHoursSA_CheckedChanged(object sender, EventArgs e)
        {
            ResetControls();            
        }

        private void cbMaximumHoursSR_CheckedChanged(object sender, EventArgs e)
        {

            ResetControls();
        }

        private void btnResetDefaults_Click(object sender, EventArgs e)
        {
            SetDefaultValues();
        }

        private void cbAvoidInArow_CheckedChanged(object sender, EventArgs e)
        {
            ResetControls();
        }

        private void mbFullShifts_TextChanged(object sender, EventArgs e)
        {
            ResetControls();
        }

        readonly Int64[] GetLastWeekClosers;

        private void btnGo_Click(object sender, EventArgs e)
        {
            if (!cbMaximumHoursSR.Checked)
            {
                GetResulting.StoreRunnersMaximumHours = 0;
            }
            if (!cbMaximumHoursSA.Checked)
            {
                GetResulting.StoreAssistantsMaximumHours = 0;
            }
            if (!cbAvoidInArow.Checked)
            {
                GetResulting.MaximumFullShiftsInARow = 0;
            }
            GetResulting.LastWeekClosers = GetLastWeekClosers;
        }

        

    }
}
